;; divide by 16

(defun count-from-end-with-length-4 (x list length)
  (declare (optimize (speed 3) (debug 0) (safety 0) (compilation-speed 0)))
  (declare (type fixnum length))
  (let ((count 0))
    (declare (type fixnum count))
    (flet ((process (elem)
	     (when (eq elem x)
	       (incf count))))
      (labels ((recursive-traverse (rest length)
		 (declare (type fixnum length))
		 (when (> length 0)
		     (recursive-traverse (cdr rest) (1- length))
		     (process (car rest))))
	       (traverse (rest length)
		 (declare (type fixnum length))
;;		 (print (list 'traverse (length rest) length))
		 (if (< length 16384)
		     (recursive-traverse rest length)
		     (let* ((f (ash length -4))
			    (r0 rest) (r1 (nthcdr f r0)) (r2 (nthcdr f r1)) (r3 (nthcdr f r2)) 
			    (r4 (nthcdr f r3)) (r5 (nthcdr f r4)) (r6 (nthcdr f r5)) (r7 (nthcdr f r6))
			    (r8 (nthcdr f r7)) (r9 (nthcdr f r8)) (r10 (nthcdr f r9)) (r11 (nthcdr f r10))
			    (r12 (nthcdr f r11)) (r13 (nthcdr f r12)) (r14 (nthcdr f r13)) (r15 (nthcdr f r14)))
		       (traverse (nthcdr f r15) (- length (ash f 16)))
		       (traverse r15 f) (traverse r14 f) (traverse r13 f) (traverse r12 f) (traverse r11 f)
		       (traverse r10 f) (traverse r9 f) (traverse r8 f) (traverse r7 f) (traverse r6 f)
		       (traverse r5 f) (traverse r4 f) (traverse r3 f) (traverse r2 f) (traverse r1 f)
		       (traverse rest f)))))
	       (traverse list length)
	       count))))

(defun reverse-count-4 (x list)
  (count-from-end-with-length-4 x list (length list)))
